package cn.bbstone.pisces2.ui.base.notify;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.e4.core.services.events.IEventBroker;
import org.osgi.service.component.annotations.Component;

import cn.bbstone.pisces2.listener.IListenerRegister;
import cn.bbstone.pisces2.listener.OpEnum;
import cn.bbstone.pisces2.listener.OpUtil;
import cn.bbstone.pisces2.ui.base.enums.CmdEnum;
import cn.bbstone.pisces2.ui.views.statusbar.ConnectionEnum;
import cn.bbstone.pisces2.ui.views.statusbar.PresenceEnum;

@Component
public class Pi2ListenerRegister implements IListenerRegister {

	private IEventBroker eventBroker;
	private List<OpEnum> filter = new ArrayList<>();

	@Override
	public void register() {

		onServerStartup();

		onServerShutdown();

		onClientStartup();

		onClientShutdown();

		onClientBizMetaCreated();

		onClientConnected();
		
		onClientDisconnected();
		
		onServerDisconnected();

		// others operation listeners
		for (OpEnum opEnum : OpEnum.values()) {
			if (filter.contains(opEnum))
				continue;
//			if (OpEnum.s4_done_startup_server.equals(opEnum)) continue;
			OpUtil.addListener(opEnum, opEvent -> {
				eventBroker.post(Pi2Events.OPERATION, opEnum.getDisplayText());
//                        log.info("opMsg: {}", opEvent.getOp().getDisplayText());
			});
		}
	}

	public void setEventBroker(IEventBroker eventBroker) {
		this.eventBroker = eventBroker;
	}

	/**
	 * when click startup button on Server UI
	 */
	private void onServerStartup() {
		OpUtil.addListener(OpEnum.s4_done_startup_server, opEvent -> {
			// --------------------------------------- notify status bar update after
			// startup success
			// update operation displayText
			eventBroker.post(Pi2Events.OPERATION, OpEnum.s4_done_startup_server.getDisplayText());
			// update presence icon & text
			eventBroker.post(Pi2Events.PRESENCE, PresenceEnum.online);
			// --------------------------------------- notify UI update after startup
			// success
			// notify save-point part
			eventBroker.post(Pi2Events.SERVER_STARTUP_SAVEPOINT, CmdEnum.startup);
			// notify file list part
			eventBroker.post(Pi2Events.SERVER_STARTUP_FILELIST, CmdEnum.startup);
			// notify connection information part
			eventBroker.post(Pi2Events.SERVER_STARTUP_CONNINFO, CmdEnum.startup);
			// notify startup command handler
			eventBroker.post(Pi2Events.SERVER_STARTUP_HANDLER, CmdEnum.startup);

			//

		});
		filter.add(OpEnum.s4_done_startup_server);

	}

	/**
	 * when click shutdown button on Server UI
	 */
	private void onServerShutdown() {
		OpUtil.addListener(OpEnum.s99_server_shutdown, opEvent -> {
			// --------------------------------------- notify status bar update after
			// startup success
			// update operation displayText
			eventBroker.post(Pi2Events.OPERATION, OpEnum.s99_server_shutdown.getDisplayText());
			// update presence icon & text
			eventBroker.post(Pi2Events.PRESENCE, PresenceEnum.offline);
			// --------------------------------------- notify UI update after startup
			// success
//			// notify save-point part
//			eventBroker.post(Pi2Events.SERVER_STARTUP_SAVEPOINT, CmdEnum.stop);
//			// notify file list part
//			eventBroker.post(Pi2Events.SERVER_STARTUP_FILELIST, CmdEnum.stop);
//			// notify connection information part
//			eventBroker.post(Pi2Events.SERVER_STARTUP_CONNINFO, CmdEnum.stop);
//			// notify startup command handler
//			eventBroker.post(Pi2Events.SERVER_STARTUP_HANDLER, CmdEnum.stop);

			//

		});
		filter.add(OpEnum.s99_server_shutdown);
	}

	/**
	 *  client UI, click startup button
	 */
	private void onClientStartup() {
		OpUtil.addListener(OpEnum.s4_done_startup_client, opEvent -> {
			// --------------------------------------- notify status bar update after
			// startup success
			// update operation displayText
			eventBroker.post(Pi2Events.OPERATION, OpEnum.s4_done_startup_client.getDisplayText());
			// update presence icon & text
			eventBroker.post(Pi2Events.PRESENCE, PresenceEnum.online);
			// --------------------------------------- notify UI update after startup
			// success
			// notify save-point part
//			eventBroker.post(Pi2Events.CLIENT_STARTUP_SAVEPOINT, CmdEnum.startup);
			// notify file list part
//			eventBroker.post(Pi2Events.CLIENT_STARTUP_FILELIST, CmdEnum.startup);
			// notify connection information part
//			eventBroker.post(Pi2Events.CLIENT_STARTUP_CONNINFO, CmdEnum.startup);
			// notify startup command handler
			eventBroker.post(Pi2Events.CLIENT_STARTUP_HANDLER, CmdEnum.startup);
			// connectionItem
			eventBroker.post(Pi2Events.CONNECTION, ConnectionEnum.connected);
			// notify startup handler to set client connected status to Pi2Context
			eventBroker.post(Pi2Events.CLIENT_CONNECTED_HANDLER, CmdEnum.NA);

			//

		});
		filter.add(OpEnum.s4_done_startup_client);
	}
	
	/**
	 * When client shutdown, will trigger server disconnected
	 * 
	 */
	private void onServerDisconnected() {
		OpUtil.addListener(OpEnum.s8_server_disconnected, opEvent -> {
			// --------- notify status bar update
			// operation display text section
			eventBroker.post(Pi2Events.OPERATION, OpEnum.s8_server_disconnected.getDisplayText());
			// presence section
//			eventBroker.post(Pi2Events.PRESENCE, PresenceEnum.offline);
			// connection section
			eventBroker.post(Pi2Events.CONNECTION, ConnectionEnum.disconnected);

			// --------- notify UI update after startup
			// notify connectionInfo part
			eventBroker.post(Pi2Events.SERVER_DISCONNECTED_CONNINFO, CmdEnum.NA);

		});
		filter.add(OpEnum.s8_server_disconnected);
	}

	/**
	 * client UI, click shutdown button
	 */
	private void onClientShutdown() {
		OpUtil.addListener(OpEnum.s99_client_shutdown, opEvent -> {
			// --------- notify status bar update
			// operation display text section
			eventBroker.post(Pi2Events.OPERATION, OpEnum.s99_client_shutdown.getDisplayText());
			// presence section
			eventBroker.post(Pi2Events.PRESENCE, PresenceEnum.offline);
			// connection info Part
			eventBroker.post(Pi2Events.CONNECTION, ConnectionEnum.disconnected);
			
			// preference page
			eventBroker.post(Pi2Events.CLIENT_SHUTDOWN_CONNINFO, ConnectionEnum.disconnected);

			// --------- notify UI update after startup

		});
		filter.add(OpEnum.s99_client_shutdown);
	}


	private void onClientBizMetaCreated() {
		OpUtil.addListener(OpEnum.client_biz_meta_created, opEvent -> {
			// update operation displayText
			eventBroker.post(Pi2Events.OPERATION, OpEnum.client_biz_meta_created.getDisplayText());

			// notify save-point part
			eventBroker.post(Pi2Events.CLIENT_BIZ_META_CREATED_SAVEPOINT, CmdEnum.NA);

			// notify file list part
			eventBroker.post(Pi2Events.CLIENT_BIZ_META_CREATED_FILELIST, CmdEnum.NA);

		});
		filter.add(OpEnum.client_biz_meta_created);
	}
	

	/**
	 * Client startup and connected to server
	 * 
	 */
	private void onClientConnected() {
		OpUtil.addListener(OpEnum.s5_client_connected, opEvent -> {
			// --------- notify status bar update
			// operation display text section
			eventBroker.post(Pi2Events.OPERATION, OpEnum.s5_client_connected.getDisplayText());
			// presence section
//			eventBroker.post(Pi2Events.PRESENCE, PresenceEnum.offline);
			// connection section
			eventBroker.post(Pi2Events.CONNECTION, ConnectionEnum.connected);

			// --------- notify UI update after startup
			// notify connectionInfo part // only string(clientAddr), not json format
			eventBroker.post(Pi2Events.CLIENT_CONNECTED_CONNINFO, opEvent.getJsonMsg());

		});
		filter.add(OpEnum.s5_client_connected);
	}
	
	/**
	 * When Server shutdown, will client disconnected
	 */
	private void onClientDisconnected() {
		OpUtil.addListener(OpEnum.s6_client_disconnected, opEvent -> {
			// --------- notify status bar update
			// operation display text section
			eventBroker.post(Pi2Events.OPERATION, OpEnum.s6_client_disconnected.getDisplayText());
			// presence section
//			eventBroker.post(Pi2Events.PRESENCE, PresenceEnum.offline);
			// connection section
			eventBroker.post(Pi2Events.CONNECTION, ConnectionEnum.disconnected);

			// --------- notify UI update after startup
			// notify connectionInfo part // only string, not json format
			eventBroker.post(Pi2Events.CLIENT_DISCONNECTED_CONNINFO, opEvent.getJsonMsg()); 

		});
		filter.add(OpEnum.s6_client_disconnected);
	}

}
